package com.kamistoat.meimeimall.common.threadlocal;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * ThreadLocal操作类
 */
public class ThreadLocalContextHolder {
    // 为了让一个ThreadLocal直接就能存放很多值，直接把ThreadLocal绑定的值类型设置为Map
    private static final ThreadLocal<Map<String, Object>> THREAD_LOCAL = new ThreadLocal<>();

    /**
     * 向 ThreadLocal中的 map中存放 kv对
     *
     * @param key
     * @param value
     */
    public static void set(String key, Object value) {
        Map<String, Object> localMap = getLocalMap();
        localMap.put(key, value == null ? "" : value);
    }

    /**
     * 从 ThreadLocal中的 map中根据 key提取出 object，将object转换为String
     * 使用 Convert 中的静态方法 toStr进行转换
     *
     * @param key
     * @return
     */
    public static Object get(String key) {
        Map<String, Object> localMap = getLocalMap();
        return localMap.getOrDefault(key, "");
    }

    /**
     * 获取当前线程的 ThreadLocal 绑定的那个 Map
     *
     * @return
     */
    public static Map<String, Object> getLocalMap() {
        Map<String, Object> stringObjectMap = THREAD_LOCAL.get();
        if (stringObjectMap == null) {
            // 注意，使用的是 ConcurrentHashMap，相比与普通的HashMap，在多线程下的安全性更高，不会出现成环的问题
            stringObjectMap = new ConcurrentHashMap<String, Object>();
            THREAD_LOCAL.set(stringObjectMap);
        }
        return stringObjectMap;
    }

    /**
     * 设置当前线程的 ThreadLocal 绑定的那个 Map
     *
     * @param threadLocalMap
     */
    public static void setLocalMap(Map<String, Object> threadLocalMap) {
        THREAD_LOCAL.set(threadLocalMap);
    }

    /**
     * 清空当前线程的 ThreadLocal
     */
    public static void remove() {
        THREAD_LOCAL.remove();
    }

}
